/*!
 * \file MQManager.cpp
 * \project	WonderTrader
 *
 * \author Wesley
 * \date 2020/03/30
 * 
 * \brief 消息队列管理器实现文件
 * 
 * \details 本文件实现了WonderTrader消息队列系统的管理器类：
 *          - 实现服务器和客户端的生命周期管理
 *          - 提供消息发布和订阅功能的统一调度
 *          - 管理多个服务器和客户端实例
 *          - 实现日志记录和错误处理机制
 *          - 基于智能指针实现资源自动管理
 */
#include "MQManager.h"

#include <spdlog/fmt/fmt.h>

USING_NS_WTP;

/**
 * @brief 创建消息服务器
 * @details 创建新的消息服务器实例，初始化并加入管理列表
 * @param url 服务器URL地址
 * @param confirm 是否启用确认机制
 * @return WtUInt32 服务器唯一标识ID
 */
WtUInt32 MQManager::create_server(const char* url, bool confirm)
{
	// 创建新的服务器实例
	MQServerPtr server(new MQServer(this));

	printf("init server\r\n");
	// 初始化服务器
	server->init(url, confirm);

	// 获取服务器ID
	auto id = server->id();

	// 将服务器加入管理列表
	_servers[id] = server;
	return id;
}

/**
 * @brief 销毁消息服务器
 * @details 根据ID销毁指定的消息服务器实例
 * @param id 服务器ID
 */
void MQManager::destroy_server(WtUInt32 id)
{
	auto it = _servers.find(id);
	if(it == _servers.end())
	{
		log_server(id, fmt::format("MQServer {} not exists", id).c_str());
		return;
	}

	// 从管理列表中移除服务器
	_servers.erase(it);
	log_server(id, fmt::format("MQServer {} has been destroyed", id).c_str());
}

/**
 * @brief 发布消息
 * @details 通过指定服务器发布消息到指定主题
 * @param id 服务器ID
 * @param topic 消息主题
 * @param data 消息数据指针
 * @param dataLen 消息数据长度
 */
void MQManager::publish_message(WtUInt32 id, const char* topic, const void* data, WtUInt32 dataLen)
{
	auto it = _servers.find(id);
	if (it == _servers.end())
	{
		log_server(id, fmt::format("MQServer {} not exists", id).c_str());
		return;
	}

	// 获取服务器实例并发布消息
	MQServerPtr& server = (MQServerPtr&)it->second;
	server->publish(topic, data, dataLen);
}

/**
 * @brief 服务器日志记录
 * @details 记录服务器相关的日志信息
 * @param id 服务器ID
 * @param message 日志消息内容
 */
void MQManager::log_server(WtUInt32 id, const char* message)
{
	if (_cb_log)
		_cb_log(id, message, true);
}

/**
 * @brief 客户端日志记录
 * @details 记录客户端相关的日志信息
 * @param id 客户端ID
 * @param message 日志消息内容
 */
void MQManager::log_client(WtUInt32 id, const char* message)
{
	if (_cb_log)
		_cb_log(id, message, false);
}

/**
 * @brief 创建消息客户端
 * @details 创建新的消息客户端实例，初始化并加入管理列表
 * @param url 服务器URL地址
 * @param cb 消息接收回调函数
 * @return WtUInt32 客户端唯一标识ID
 */
WtUInt32 MQManager::create_client(const char* url, FuncMQCallback cb)
{
	// 创建新的客户端实例
	MQClientPtr client(new MQClient(this));
	client->init(url, cb);

	// 获取客户端ID
	auto id = client->id();

	// 将客户端加入管理列表
	_clients[id] = client;
	return id;
}

/**
 * @brief 销毁消息客户端
 * @details 根据ID销毁指定的消息客户端实例
 * @param id 客户端ID
 */
void MQManager::destroy_client(WtUInt32 id)
{
	auto it = _clients.find(id);
	if (it == _clients.end())
	{
		log_client(id, fmt::format("MQClient {} not exists", id).c_str());
		return;
	}

	// 从管理列表中移除客户端
	_clients.erase(it);
	log_client(id, fmt::format("MQClient {} has been destroyed", id).c_str());
}

/**
 * @brief 订阅主题
 * @details 为指定客户端订阅消息主题
 * @param id 客户端ID
 * @param topic 要订阅的主题名称
 */
void MQManager::sub_topic(WtUInt32 id, const char* topic)
{
	auto it = _clients.find(id);
	if (it == _clients.end())
	{
		log_client(id, fmt::format("MQClient {} not exists", id).c_str());
		return;
	}

	// 获取客户端实例并订阅主题
	MQClientPtr& client = (MQClientPtr&)it->second;
	client->sub_topic(topic);
}

/**
 * @brief 启动客户端
 * @details 启动指定的消息客户端，开始接收消息
 * @param id 客户端ID
 */
void MQManager::start_client(WtUInt32 id)
{
	auto it = _clients.find(id);
	if (it == _clients.end())
	{
		log_client(id, fmt::format("MQClient {} not exists", id).c_str());
		return;
	}

	// 获取客户端实例并启动
	MQClientPtr& client = (MQClientPtr&)it->second;
	client->start();
}